using System;
namespace ch.ethz.ssh2.crypto.cipher
{
	
	/// <summary> This is CTR mode as described in draft-ietf-secsh-newmodes-XY.txt
	/// 
	/// </summary>
	/// <author>  Christian Plattner
	/// </author>
	/// <version>  2.50, 03/15/10
	/// </version>
	public class CTRMode : BlockCipher
	{
		virtual public int BlockSize
		{
			get
			{
				return blockSize;
			}
			
		}
		internal byte[] X;
		internal byte[] Xenc;
		
		internal BlockCipher bc;
		internal int blockSize;
		internal bool doEncrypt;
		
		internal int count = 0;
		
		public virtual void  init(bool forEncryption, byte[] key)
		{
		}
		
		public CTRMode(BlockCipher tc, byte[] iv, bool doEnc)
		{
			bc = tc;
			blockSize = bc.BlockSize;
			doEncrypt = doEnc;
			
			if (blockSize != iv.Length)
				throw new System.ArgumentException("IV must be " + blockSize + " bytes long! (currently " + iv.Length + ")");
			
			X = new byte[blockSize];
			Xenc = new byte[blockSize];
			
			Array.Copy(iv, 0, X, 0, blockSize);
		}
		
		public void  transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
		{
			bc.transformBlock(X, 0, Xenc, 0);
			
			for (int i = 0; i < blockSize; i++)
			{
				dst[dstoff + i] = (byte) (src[srcoff + i] ^ Xenc[i]);
			}
			
			for (int i = (blockSize - 1); i >= 0; i--)
			{
				X[i]++;
				if (X[i] != 0)
					break;
			}
		}
	}
}